package com.airtight.programs;

import android.content.Context;
import android.opengl.GLES20;

import com.airtight.util.TextResourceReader;

import static android.opengl.GLES20.glUseProgram;

public class ShaderProgram {
    // Uniform constants
    protected static final String A_COLOR = "a_Color";
    // Shader program
    final int program;

    ShaderProgram(Context context, int vertexShaderResourceId, int fragmentShaderResourceId) {
    // Compile the shaders and link the program.
        String vertexShaderSource = TextResourceReader.readTextFileFromResource(context, vertexShaderResourceId);
        String fragmentShaderSource = TextResourceReader.readTextFileFromResource(context, fragmentShaderResourceId);
        program = buildProgram(vertexShaderSource,fragmentShaderSource);
    }

    private static int compileVertexShader(String shaderCode){
        return compileShader(GLES20.GL_VERTEX_SHADER,shaderCode);
    }

    private static int compileFragmentShader(String shaderCode) {
        return compileShader(GLES20.GL_FRAGMENT_SHADER, shaderCode);
    }

    /** creates a shader object*/
    private static int compileShader(int type, String shaderCode){
        final int shaderObjectId = GLES20.glCreateShader(type);                                     //distinct shader object Id

        GLES20.glShaderSource(shaderObjectId, shaderCode);                                          //uploads shader source code into the shader object
        GLES20.glCompileShader(shaderObjectId);                                                     //compiles shader object
        return shaderObjectId;
    }

    /**creates a program*/
    private static int buildProgram(String vertexShaderSource, String fragmentShaderSource) {
        // Compile the shaders.
        int vertexShader = compileVertexShader(vertexShaderSource);
        int fragmentShader = compileFragmentShader(fragmentShaderSource);
        return linkProgram(vertexShader, fragmentShader);
    }

    /** attaches two shaders to a program*/
    private static int linkProgram(int vertexShaderId, int fragmentShaderId) {
        final int programObjectId = GLES20.glCreateProgram();

        GLES20.glAttachShader(programObjectId, vertexShaderId);                                     //attaches the vertex shader
        GLES20.glAttachShader(programObjectId, fragmentShaderId);                                   //attaches the fragment shader
        GLES20.glLinkProgram(programObjectId);                                                      //links the program

        return programObjectId;
    }

    /**uses this program for all the following operations*/
    public void useProgram() {
    // Set the current OpenGL shader program to this program.
        glUseProgram(program);
    }
}
